#!/usr/bin/env ruby

class Svn
  TRUNK = "trunk"
  TAGS = "tags"
  BRANCH = "branches"
  NEW_MESSAGE = "New version realized."
  
  attr_accessor :path, :info
  
  def initialize(path = nil)
    if !path.nil?
      @path = path.to_s
    end
  end

  def isSvn?
    !info.nil? and info.size > 0 and isPathLocal?(info["Path"])
  end

  def isPathLocal?(path=nil)
    path = info_path if path.nil?
    self.class.isPathLocal?(path)
  end

  def self.isPathLocal?(path)
    File.exist?(path)
  end

  # TODO: if path is empty in info, path_local errored. Class not initialized.
  def info
    @info = Hash[svn_cmd("info",self.path_local(@path)).split("\n").collect{|i| [i.split(":")[0].strip, i.split(":")[1..-1].join(":").strip]}] if @info.nil? or @info.size == 0
    @info = Hash[svn_cmd("info",@path).split("\n").collect{|i| [i.split(":")[0].strip, i.split(":")[1..-1].join(":").strip]}] if @info.nil? or @info.size == 0
    @info
  end

  def info_url
    info["URL"] if !info.nil?
  end

  def info_path
    if isSvn?
      info["Path"]
    else
      @path
    end
  end

  def head_path
    info_path.split(/#{TAGS}|#{TRUNK}|#{BRANCH}/)[0]
  end

  def head_url
    info_url.split(/#{TAGS}|#{TRUNK}|#{BRANCH}/)[0]
  end

  def tags
    svn_cmd("list", File.join(head_url, TAGS))
  end

  def isTag?(tag)
    tags.index(tag) != nil
  end

  # TODO: If version of tag exist trunk folder created in existed tag. 
  def tag_new(tag, message = NEW_MESSAGE)
    tagPath = File.join(head_url, TAGS, tag)
    trunkPath = File.join(head_url, TRUNK)
    if svn_cmd("info", trunkPath).size > 0
      svn_cmd("rm", tagPath, "-m '#{message}'") if isTag?(tag)
      svn_cmd("cp", [trunkPath, tagPath], "-m '#{message}'")
    end
  end

  def commit(message = NEW_MESSAGE,path = info_path)
    message = NEW_MESSAGE if message.to_s == ""
    svn_cmd("ci", path, "-m '#{message}'")
  end
  
  def status
    svn_cmd("st", info_path)
  end

  def to_s
    info.to_s
  end

  def svn_cmd(cmd, path=nil, params=nil)
    self.class.svn_cmd(cmd, path, params)
  end

  def self.svn_cmd(cmd, path=nil, params=nil)
    path = path.join(" ") if path.class == [].class
    params = params.join(" ") if params.class == [].class
    puts svn = "svn #{cmd} #{path} #{params}"
    `#{svn}`
  end

  def svn_init(url=nil, path=nil)
    url = info_url if url.nil?
    path = path_local if path.nil?
    if !isPathLocal?(path) or !isSvn?
      svn_cmd("co", [url, path], "-q")
    else
      svn_cmd("up", path, "-q")
    end
    @info = nil
    info
  end
  
  def path_local(path=nil)
    path = self.class.path_local(path) if !path.nil?
    path = self.class.path_local(info_path) if path.nil?
    path = self.class.path_local(info_url) if path.nil?
    path
  end
  
  def self.path_local(path)
    tmp = File.join(Dir.tmpdir, "svn_co")
    path = File.join(tmp, path.split("/")[3..-1].join("/")) if !isPathLocal?(path) and !path.index(":").nil? and path.split("/").size > 3
    path = File.join(tmp, path) if !isPathLocal?(path) and path.index(":").nil?
    path
  end
  
end